//编码器
//已通过示波器测量: 最小检测间隔2ms
//  只能用 Encode_Key检测按键按下, 完整检测过程: 下降沿触发检测,低电平持续100ms以上并有上升沿,则该按键有效
//  只能用 Encode_A,Encode_B通过脉冲检测旋钮(高低电平判断无效,实际测试旋钮后会持续高或者低电平)，不能检测按键
//逆时针:
//	A: 0 0 1
//	B: 1 0 0
//顺时针: 
//	A: 1 0 0
//	B: 0 0 1
//  旋钮卡在卡点开头: Encode_A一直是低电平, Encode_B一直是高电平 
//  旋钮卡在卡点结尾: Encode_B一直是低电平, Encode_A一直是高电平 
//  一个完整的脉冲才是旋钮的一个卡点
//  [0-20]个脉冲对应旋转速度, 取4个脉冲以上温度设定值递增5有效


#include "Encoder.h"



EncoderParam_S EncoderParam;
uint16_t Tick10ms;
uint8_t IsKey1;
bool Encoder_Key = 0;
bool Encoder_LongKey = 0;
bool Encoder_TurnL = 0;
bool Encoder_TurnR = 0;


void Encoder_Key_Handler(void)
{
	Encoder_Key = 1;  //代表旋钮按下，使用时需要清零
}
void Encoder_LongKey_Handler(void)
{
	Encoder_LongKey = 1;  //代表旋钮长按，使用时需要清零
}
void Encoder_TurnL_Handler(void)
{
	Encoder_TurnL = 1;  //代表旋钮左旋，使用时需要清零
}
void Encoder_TurnR_Handler(void)
{
	Encoder_TurnR = 1;  //代表旋钮右旋，使用时需要清零
}

void Encoder_TurnSpeed(uint8_t param)
{
	if(param == 0) param = 1;
	EncoderParam.TurnCount = param;
}

//旋钮探测
void Encoder_Knob_Detection(void)
{
	if ((GPIO_ReadEncoderA == 0) && (GPIO_ReadEncoderB == 1))
	{
		EncoderParam.ASamping = 1;
	}
	if ((GPIO_ReadEncoderA == 0) && (GPIO_ReadEncoderB == 0))
	{
		if(EncoderParam.ASamping == 1) EncoderParam.ASamping = 2;
	}
	if ((GPIO_ReadEncoderA == 1) && (GPIO_ReadEncoderB == 0))
	{
		if(EncoderParam.ASamping == 2) EncoderParam.ASamping = 3;
	}

	if ((GPIO_ReadEncoderA == 1) && (GPIO_ReadEncoderB == 0))
	{
		EncoderParam.BSamping = 1;
	}
	if ((GPIO_ReadEncoderA == 0) && (GPIO_ReadEncoderB == 0))
	{
		if(EncoderParam.BSamping == 1) EncoderParam.BSamping = 2;
	}
	if ((GPIO_ReadEncoderA == 0) && (GPIO_ReadEncoderB == 1))
	{
		if(EncoderParam.BSamping == 2) EncoderParam.BSamping = 3;
	}

	if(EncoderParam.BSamping == 3)
	{ //解析出单次顺旋转
		EncoderParam.BSamping = 0;
		if(EncoderParam.TurnRCount < 0xff) EncoderParam.TurnRCount++;
		if (EncoderParam.TurnRCount >= EncoderParam.TurnCount)
		{ //顺旋转有效, 4:旋转45°检测有效, 8:旋转90°检测有效
			EncoderParam.TurnRCount = 0;
			if(EncoderParam.IsTurnR < 10) EncoderParam.IsTurnR++;
		}
		EncoderParam.TurnLCount = 0;
		EncoderParam.IsTurnL = 0;
	}
	else if(EncoderParam.ASamping == 3)
	{ //解析出单次逆旋转
		EncoderParam.ASamping = 0;
		if(EncoderParam.TurnLCount < 0xff) EncoderParam.TurnLCount++;
		if (EncoderParam.TurnLCount >= EncoderParam.TurnCount)
		{ //逆旋转有效
			EncoderParam.TurnLCount = 0;
			if(EncoderParam.IsTurnL < 10) EncoderParam.IsTurnL++;
		}
		EncoderParam.TurnRCount = 0;
		EncoderParam.IsTurnR = 0;
	}
}

void EncoderInit(void)
{
	IO_Mode_Encoder_Key();	
	IO_Mode_Encoder_A();	
	IO_Mode_Encoder_B();		

	EncoderParam.IsLongKey = 0;
	EncoderParam.IsLongKeyCount = 0;

	Encoder_TurnSpeed(2);
}

void EncoderMain(void)
{
	if(EncoderParam.IsLongKey == 1)
	{ //按键长按有效
		EncoderParam.IsLongKey = 2;
		EncoderParam.IsKey = 0;

		Encoder_LongKey_Handler();
	}
	else if (EncoderParam.IsKey == 1)
	{ //按键有效
		EncoderParam.IsTurnR = 0;
		EncoderParam.IsTurnL = 0;
		EncoderParam.IsKey = 0;

		Encoder_Key_Handler();
	}
	if (EncoderParam.IsTurnR > 0)
	{ //顺时旋钮有效
		EncoderParam.IsTurnR--;

		Encoder_TurnR_Handler();
	}
	else if (EncoderParam.IsTurnL > 0)
	{ //逆时旋钮有效
		EncoderParam.IsTurnL--;

		Encoder_TurnL_Handler();
	}
	encode();
}

//Tick 2ms
//有了FreeRTOS,不再需要定时器
void EncoderClock(void)
{
	static uint16_t count = 0;

	//按键检测
	if (GPIO_ReadEncoderKey == 0x00)
	{ //按下
		if(EncoderParam.KeyDownCount < 0xff) EncoderParam.KeyDownCount++;
		if (EncoderParam.KeyDownCount >= 2)
		{ //2ms * 6
			if(GPIO_ReadEncoderKey == 0x00)
			{
				if(EncoderParam.KeyUpCount < 0xff) EncoderParam.KeyUpCount++;
				if(count < 0xffff) count++;
			  if(count > 100)	
				{ //旋钮中间按键 按下
					
					
				}
				if(count >= 750)
				{ //旋钮中间按键持续3s有效
					if(EncoderParam.IsLongKey == 0) EncoderParam.IsLongKey = 1;
				}
			}
			else
			{
				EncoderParam.KeyUpCount = 0;
				count = 0;
			}
		}
	}
	else
	{ //释放
		if(EncoderParam.KeyDownCount > 0) EncoderParam.KeyDownCount--;
		if (EncoderParam.KeyUpCount >= 1)
		{
			EncoderParam.IsKey = 1;
		}
		if(EncoderParam.IsLongKey > 0) EncoderParam.IsKey = 0;
		EncoderParam.IsLongKey = 0;
		EncoderParam.KeyUpCount = 0;

		if(count >= 100)
		{
			
			
		}
		count = 0;

		Encoder_Knob_Detection(); //旋钮按键释放后,才能探测旋转
	}
}
